/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.cef.generator.entityGenerator.entity;

import com.inspur.edp.caf.generator.BaseGenerator;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.element.GspAssociation;
import com.inspur.edp.cef.generator.entityGenerator.base.DataTypeGenerator;
import com.inspur.edp.cef.generator.entityGenerator.base.DataTypeGeneratorContext;
import com.inspur.edp.cef.generator.entityGenerator.base.dataTypeData.DataTypeDataGenerator;
import com.inspur.edp.cef.generator.entityGenerator.base.elements.ElementEnumGenerator;
import com.inspur.edp.cef.generator.entityGenerator.entity.elements.EntityElementAssGenerator;
import com.inspur.edp.cef.generator.entityGenerator.entity.elements.EntityElementEnumGenerator;
import com.inspur.edp.cef.generator.entityGenerator.entity.entityData.EntityDataGenerator;
import com.inspur.edp.das.commonmodel.IGspCommonObject;
import lombok.var;

import java.util.ArrayList;

public abstract class EntityNodeGenerator extends DataTypeGenerator {
  protected EntityNodeGenerator(
          IGspCommonObject commonObject, CMEntityGeneratorContext entityGenContext) {
    super(commonObject, entityGenContext);
  }
  
  protected EntityNodeGeneratorContext getContext() {
    EntityNodeGeneratorContext context = (EntityNodeGeneratorContext) super.getContext();
    entityGenContext.getDataTypeGenContexts().put(super.dataType.getCode(), context);
    return context;
  }

  @Override
  protected final DataTypeGeneratorContext createDataTypeGenContext() {
    return createEntityNodeGeneratorContext();
  }

  protected abstract EntityNodeGeneratorContext createEntityNodeGeneratorContext();

  @Override
  protected ArrayList<BaseGenerator> createCompositeItemGenerators() {
    ArrayList<BaseGenerator> list = getChildEntityGenerators();
    var baseGenerators = super.createCompositeItemGenerators();
    if (baseGenerators != null) {
      list.addAll(baseGenerators);
    }
    // list.add(new EntityDataSerializerGenerator(Context));
    return list;
  }

  private ArrayList<BaseGenerator> getChildEntityGenerators() {
    ArrayList<BaseGenerator> list = new ArrayList<BaseGenerator>();
    if (getContext().getCommonObject().getContainChildObjects() == null
        || getContext().getCommonObject().getContainChildObjects().size() == 0) {
      return list;
    }

    for (var item : getContext().getCommonObject().getContainChildObjects()) {
      list.add(getChildObjectGenerator(item));
    }
    return list;
  }

  private BaseGenerator getChildObjectGenerator(IGspCommonObject childObject) {
    return createChildObjectGenerator(childObject);
  }

  protected abstract EntityNodeGenerator createChildObjectGenerator(IGspCommonObject childObject);

  @Override
  protected BaseGenerator getFieldAssClassGenerator(
      IGspCommonField field, GspAssociation association) {
    return new EntityElementAssGenerator(field, association, getContext());
  }

  @Override
  protected ElementEnumGenerator getElementEnumClassGenerator(IGspCommonField field) {
    return new EntityElementEnumGenerator(field, getContext());
  }

  @Override
  protected final DataTypeDataGenerator getDataGenerator() {
    return getEntityDataGenerator();
  }

  protected abstract EntityDataGenerator getEntityDataGenerator();
}
